package com.heima.home.service.impl;

import com.heima.home.dto.ReviewsDTO;
import com.heima.home.entity.Bookings;
import com.heima.home.entity.Properties;
import com.heima.home.entity.Reviews;
import com.heima.home.entity.Users;
import com.heima.home.exception.CustomException;
import com.heima.home.mapper.BookingMapper;
import com.heima.home.mapper.PropertyMapper;
import com.heima.home.mapper.ReviewsMapper;
import com.heima.home.mapper.UserMapper;
import com.heima.home.service.PropertyService;
import com.heima.home.service.ReviewsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Slf4j
@Service
public class ReviewsServiceImpl implements ReviewsService {
    @Autowired
    private ReviewsMapper reviewsMapper;
    @Autowired
    private BookingMapper bookingMapper;
    @Autowired
    private PropertyMapper propertyMapper;
    @Autowired
    private UserMapper userMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addReviews(ReviewsDTO reviewsDTO) {
        try {
            // 1. 校验订单是否存在
            Bookings bookings = bookingMapper.selectBookingById(reviewsDTO.getBookingId());
            if (bookings == null) {
                log.warn("评价失败，订单不存在: bookingId={}", reviewsDTO.getBookingId());
                throw new CustomException("订单不存在");
            }
            
            // 2. 校验是否是订单的使用者
            if (!bookings.getUserId().equals(reviewsDTO.getUserId().longValue())) {
                log.warn("评价失败，用户无权评价: userId={}, bookingUserId={}",
                        reviewsDTO.getUserId(), bookings.getUserId());
                throw new CustomException(HttpStatus.FORBIDDEN.value(), "您无权评价该订单");
            }
            
            // 3. 设置房源和房东ID
            reviewsDTO.setPropertyId(bookings.getPropertyId());
            reviewsDTO.setHostId(bookings.getHostId());

            // 4. 添加评价
            int result = reviewsMapper.addReviews(reviewsDTO);
            if (result <= 0) {
                log.error("评价添加失败: bookingId={}", reviewsDTO.getBookingId());
                throw new CustomException("评价添加失败");
            }
            log.info("评价添加成功: bookingId={}", reviewsDTO.getBookingId());
            return result;
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("添加评价异常: bookingId={}", reviewsDTO.getBookingId(), e);
            throw new CustomException("添加评价失败，请稍后重试");
        }
    }

    @Override
    public List<ReviewsDTO> showAllReviewsByUserId(Integer userId) {
        if (userId == null || userId <= 0) {
            throw new CustomException("用户ID不合法");
        }
        try {
            List<ReviewsDTO> reviews = reviewsMapper.showAllReviewsByUserId(userId);
            
            // 填充房源名称和订单编号
            for (ReviewsDTO review : reviews) {
                if (review.getBookingId() != null) {
                    Bookings booking = bookingMapper.selectBookingById(review.getBookingId());
                    if (booking != null) {
                        review.setBookingNo(booking.getBookingNo());
                    }
                }
                if (review.getPropertyId() != null) {
                    Properties property = propertyMapper.selectById(review.getPropertyId());
                    if (property != null) {
                        review.setPropertyName(property.getTitle());
                    }
                }
            }
            
            return reviews;
        } catch (Exception e) {
            log.error("查询评价列表异常: userId={}", userId, e);
            throw new CustomException("查询评价列表失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteReviews(Integer id, Integer currentUserId) {
        if (id == null || id <= 0) {
            throw new CustomException("评价ID不合法");
        }
        if (currentUserId == null || currentUserId <= 0) {
            throw new CustomException("用户ID不合法");
        }
        
        try {
            // 1. 查询评价是否存在
            Reviews review = reviewsMapper.findById(id);
            if (review == null) {
                log.warn("删除失败，评价不存在: id={}", id);
                throw new CustomException("评价不存在");
            }
            
            // 2. 校验权限
            if (!review.getUserId().equals(currentUserId.longValue())) {
                log.warn("删除失败，用户无权删除: userId={}, reviewUserId={}", 
                        currentUserId, review.getUserId());
                throw new CustomException(HttpStatus.FORBIDDEN.value(), "您无权删除该评价");
            }
            
            // 3. 执行删除
            boolean result = reviewsMapper.deleteReviews(id);
            if (!result) {
                log.error("评价删除失败: id={}", id);
                throw new CustomException("删除评价失败");
            }
            
            return result;
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除评价异常: id={}", id, e);
            throw new CustomException("删除评价失败，请稍后重试");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateReviews(ReviewsDTO reviewsDTO, Integer currentUserId) {
        if (reviewsDTO == null || reviewsDTO.getId() == null) {
            throw new CustomException("评价ID不能为空");
        }
        if (currentUserId == null || currentUserId <= 0) {
            throw new CustomException("用户ID不合法");
        }
        
        try {
            // 1. 查询评价是否存在
            Reviews review = reviewsMapper.findById(reviewsDTO.getId());
            if (review == null) {
                log.warn("修改失败，评价不存在: id={}", reviewsDTO.getId());
                throw new CustomException("评价不存在");
            }
            
            // 2. 校验权限
            if (!review.getUserId().equals(currentUserId.longValue())) {
                log.warn("修改失败，用户无权修改: userId={}, reviewUserId={}", 
                        currentUserId, review.getUserId());
                throw new CustomException(HttpStatus.FORBIDDEN.value(), "您无权修改该评价");
            }
            
            // 3. 执行修改
            boolean result = reviewsMapper.updateReviews(reviewsDTO);
            if (!result) {
                log.error("评价修改失败: id={}", reviewsDTO.getId());
                throw new CustomException("修改评价失败");
            }
            
            return result;
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("修改评价异常: id={}", reviewsDTO.getId(), e);
            throw new CustomException("修改评价失败，请稍后重试");
        }
    }

    @Override
    public List<ReviewsDTO> findByPropertyId(Integer propertyId) {
        if (propertyId == null || propertyId <= 0) {
            throw new CustomException("房源ID不合法");
        }
        try {
            List<ReviewsDTO> reviews = reviewsMapper.findByPropertyId(propertyId);
            // 填充房源名称和订单编号和用户名称
            for (ReviewsDTO review : reviews) {
                if (review.getBookingId() != null) {
                    Bookings booking = bookingMapper.selectBookingById(review.getBookingId());
                    if (booking != null) {
                        review.setBookingNo(booking.getBookingNo());
                    }
                }
                if (review.getPropertyId() != null) {
                    Properties property = propertyMapper.selectById(review.getPropertyId());
                    if (property != null) {
                        review.setPropertyName(property.getTitle());
                    }
                }
                if (review.getUserId() != null) {
                    Users users = userMapper.findById(review.getUserId());
                    if (users != null) {
                        review.setUserName(users.getUsername());
                    }
                }
            }
            
            return reviews;
        } catch (Exception e) {
            log.error("查询房源评价异常: propertyId={}", propertyId, e);
            throw new CustomException("查询房源评价失败");
        }
    }
}
